Vue.js 待办事项应用教程

1. Vue.js 简介和特性

Vue.js 是一个渐进式 JavaScript 框架,用于构建用户界面。它易于上手,同时功能强大,支持组件化开发、响应式数据绑定和虚拟 DOM 等特性。

特性

  • 组件化开发:将界面拆分为多个可复用的组件。
  • 响应式数据绑定:数据变化自动更新视图。
  • 虚拟 DOM:提高渲染性能。
  • 丰富的生态系统:支持路由、状态管理、测试等。

2. 开发环境搭建

2.1 Vue CLI

Vue CLI 是一个官方提供的脚手架工具,用于快速搭建 Vue 项目。

npm install -g @vue/cli
vue create todo-app

2.2 Vite

Vite 是一个新型前端构建工具,启动速度快,适合开发小型到中型项目。

npm init vite@latest todo-app --template vue

3. 创建第一个 Vue 应用

3.1 项目结构

todo-app/
├── public/
├── src/
│   ├── assets/
│   ├── components/
│   ├── App.vue
│   ├── main.js
├── package.json

3.2 运行项目

cd todo-app
npm install
npm run dev

4. Vue 实例和生命周期

4.1 Vue 实例

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
});

4.2 生命周期钩子

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  },
  created() {
    console.log('Vue instance created');
  },
  mounted() {
    console.log('Vue instance mounted');
  }
});

5. 模板语法和数据绑定

5.1 插值

<div id="app">
  {{ message }}
</div>

5.2 指令

<div id="app">
  <p v-if="show">This is visible</p>
  <p v-else>This is hidden</p>
</div>

6. 组件化开发

6.1 创建组件

Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
});

6.2 使用组件

<div id="app">
  <todo-item v-for="item in todos" :todo="item" :key="item.id"></todo-item>
</div>

7. 组件通信

7.1 Props

Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
});

7.2 Events

Vue.component('todo-item', {
  template: '<li @click="$emit('remove')">{{ todo.text }}</li>'
});

8. 计算属性和侦听器

8.1 计算属性

new Vue({
  el: '#app',
  data: {
    firstName: 'John',
    lastName: 'Doe'
  },
  computed: {
    fullName() {
      return this.firstName + ' ' + this.lastName;
    }
  }
});

8.2 侦听器

new Vue({
  el: '#app',
  data: {
    firstName: 'John',
    lastName: 'Doe'
  },
  watch: {
    firstName(newVal, oldVal) {
      console.log(`First name changed from ${oldVal} to ${newVal}`);
    }
  }
});

9. 条件渲染和列表渲染

9.1 条件渲染

<div id="app">
  <p v-if="show">This is visible</p>
  <p v-else>This is hidden</p>
</div>

9.2 列表渲染

<div id="app">
  <ul>
    <li v-for="item in items" :key="item.id">{{ item.text }}</li>
  </ul>
</div>

10. 表单输入绑定

10.1 单行文本

<div id="app">
  <input v-model="message" placeholder="edit me">
  <p>Message is: {{ message }}</p>
</div>

10.2 多行文本

<div id="app">
  <textarea v-model="message"></textarea>
  <p>Message is: {{ message }}</p>
</div>

11. 单文件组件 (.vue 文件)

11.1 结构

<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello Vue!'
    };
  }
};
</script>

<style scoped>
p {
  color: blue;
}
</style>

12. 组件注册

12.1 全局注册

Vue.component('my-component', {
  template: '<div>A custom component!</div>'
});

12.2 局部注册

import MyComponent from './MyComponent.vue';

export default {
  components: {
    MyComponent
  }
};

13. Scoped CSS

13.1 作用域样式

<template>
  <div class="example">Scoped CSS</div>
</template>

<style scoped>
.example {
  color: red;
}
</style>

14. CSS 预处理器 (Sass, Less)

14.1 安装

npm install sass-loader sass --save-dev

14.2 使用

<style lang="scss">
$color: red;
.example {
  color: $color;
}
</style>

15. 动态样式和类绑定

15.1 动态类

<div id="app">
  <div :class="{ active: isActive }">Dynamic Class</div>
</div>

15.2 动态样式

<div id="app">
  <div :style="{ color: activeColor, fontSize: fontSize + 'px' }">Dynamic Style</div>
</div>

16. Vue Router

16.1 安装

npm install vue-router

16.2 配置

import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from './views/Home.vue';
import About from './views/About.vue';

Vue.use(VueRouter);

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
];

const router = new VueRouter({
  routes
});

new Vue({
  router,
  render: h => h(App)
}).$mount('#app');

17. Vuex 状态管理

17.1 安装

npm install vuex

17.2 配置

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

new Vue({
  store,
  render: h => h(App)
}).$mount('#app');

18. 混入 (Mixins)

18.1 定义

const myMixin = {
  created() {
    this.hello();
  },
  methods: {
    hello() {
      console.log('hello from mixin!');
    }
  }
};

18.2 使用

new Vue({
  mixins: [myMixin],
  created() {
    console.log('component created');
  }
});

19. 自定义指令

19.1 全局指令

Vue.directive('focus', {
  inserted: function(el) {
    el.focus();
  }
});

19.2 局部指令

new Vue({
  directives: {
    focus: {
      inserted: function(el) {
        el.focus();
      }
    }
  }
});

20. 插件系统

20.1 定义

const MyPlugin = {
  install(Vue, options) {
    Vue.mixin({
      created() {
        console.log('plugin installed');
      }
    });
  }
};

20.2 使用

Vue.use(MyPlugin);

21. 虚拟 DOM 和 diff 算法

21.1 虚拟 DOM

虚拟 DOM 是 Vue 中用于提高渲染性能的一种技术,通过在内存中构建虚拟节点树,减少实际 DOM 操作。

21.2 diff 算法

diff 算法用于比较新旧虚拟 DOM 树的差异,只更新需要变化的部分,减少不必要的 DOM 操作。

22. 异步组件

22.1 定义

const AsyncComponent = () => ({
  component: import('./MyComponent.vue'),
  loading: LoadingComponent,
  error: ErrorComponent,
  delay: 200,
  timeout: 3000
});

22.2 使用

new Vue({
  components: {
    AsyncComponent
  }
});

23. keep-alive 组件缓存

23.1 使用

<keep-alive>
  <component :is="currentComponent"></component>
</keep-alive>

24. 懒加载和代码分割

24.1 懒加载

const Home = () => import('./views/Home.vue');
const About = () => import('./views/About.vue');

24.2 代码分割

import('./views/Home.vue').then(module => {
  // 使用模块
});

25. Vue DevTools

25.1 安装

npm install @vue/devtools

25.2 使用

import devtools from '@vue/devtools';

if (process.env.NODE_ENV === 'development') {
  devtools.connect();
}

26. Vue Test Utils

26.1 安装

npm install @vue/test-utils

26.2 使用

import { mount } from '@vue/test-utils';
import MyComponent from './MyComponent.vue';

test('renders correctly', () => {
  const wrapper = mount(MyComponent);
  expect(wrapper.text()).toContain('Hello Vue!');
});

27. Vue CLI

27.1 创建项目

vue create my-project

27.2 运行项目

cd my-project
npm run serve

28. Nuxt.js (Vue.js 服务端渲染框架)

28.1 安装

npx create-nuxt-app my-nuxt-app

28.2 运行项目

cd my-nuxt-app
npm run dev

29. 项目结构组织

29.1 推荐结构

my-project/
├── assets/
├── components/
├── layouts/
├── middleware/
├── pages/
├── plugins/
├── static/
├── store/
├── nuxt.config.js

30. 代码风格和规范

30.1 ESLint

npm install eslint --save-dev

30.2 Prettier

npm install prettier --save-dev

31. 错误处理和调试技巧

31.1 错误处理

Vue.config.errorHandler = function(err, vm, info) {
  console.error('Error:', err, info);
};

31.2 调试技巧

使用 Vue DevTools 进行调试,查看组件状态和事件。

32. 性能优化策略

32.1 懒加载

const Home = () => import('./views/Home.vue');

32.2 代码分割

import('./views/Home.vue').then(module => {
  // 使用模块
});

33. TypeScript 与 Vue

33.1 安装

npm install vue-class-component vue-property-decorator

33.2 使用

import { Component, Vue } from 'vue-property-decorator';

@Component
export default class MyComponent extends Vue {
  message = 'Hello Vue with TypeScript!';
}

34. 渲染函数和 JSX

34.1 渲染函数

export default {
  render(h) {
    return h('div', 'Hello Vue!');
  }
};

34.2 JSX

export default {
  render() {
    return <div>Hello Vue with JSX!</div>;
  }
};

35. 服务端渲染 (SSR)

35.1 安装

npm install vue-server-renderer

35.2 使用

const Vue = require('vue');
const renderer = require('vue-server-renderer').createRenderer();

const app = new Vue({
  template: '<div>Hello Vue SSR!</div>'
});

renderer.renderToString(app, (err, html) => {
  if (err) throw err;
  console.log(html);
});

36. 静态站点生成 (SSG)

36.1 安装

npm install nuxt

36.2 使用

npx create-nuxt-app my-nuxt-app
cd my-nuxt-app
npm run generate

37. 待办事项应用

37.1 项目结构

todo-app/
├── public/
├── src/
│   ├── assets/
│   ├── components/
│   │   ├── TodoItem.vue
│   │   ├── TodoList.vue
│   ├── App.vue
│   ├── main.js
├── package.json

37.2 实现

<!-- TodoItem.vue -->
<template>
  <li>{{ todo.text }}</li>
</template>

<script>
export default {
  props: ['todo']
};
</script>

<!-- TodoList.vue -->
<template>
  <ul>
    <todo-item v-for="item in todos" :todo="item" :key="item.id"></todo-item>
  </ul>
</template>

<script>
import TodoItem from './TodoItem.vue';

export default {
  components: {
    TodoItem
  },
  data() {
    return {
      todos: [
        { id: 1, text: 'Learn Vue' },
        { id: 2, text: 'Build an app' },
        { id: 3, text: 'Deploy to production' }
      ]
    };
  }
};
</script>

<!-- App.vue -->
<template